/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.aljfce.business.notification.control;

import com.aljfce.business.entity.Event;
import com.aljfce.business.entity.Notification;
import com.aljfce.business.entity.User;
import com.aljfce.business.mail.control.MailManager;
import com.aljfce.business.notification.exception.NotificationNotFoundException;
import java.util.Arrays;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.joda.time.DateTime;

/**
 * This class is will expose method to manage {@link Notification} objects.
 * From their creation to their deletion.
 * 
 * 
 * @author Jacopo Ferrigno <jacopo.ferrigno@gmail.com>
 */
@Stateless
public class NotificationManager {

    @PersistenceContext
    EntityManager em;

    @Inject
    Logger logger;
    
    
    public Event getNotificationDetails(Integer notificationId) throws IllegalArgumentException, NotificationNotFoundException {
        if (notificationId == null) {
            throw new IllegalArgumentException("notificationId cannot be null");
        }

        Notification notification = em.find(Notification.class, notificationId);
        if(notification == null || notification.getEventId() == null)
            throw new NotificationNotFoundException();
        
        return notification.getEventId();   
        

    }
    
    /**
     * This method will create and return a new {@link Notification} object and persist 
     * it in the persistence context.
     * 
     * 
     * @param type The type of the new notification from {@link Notification.TYPE}
     * @param user A {@link User} object representing the user to which the notification refer
     * @param event A {@link Event} object representing the event to which the notification refer 
     * @param nextSunnyDay The closest sunny day, can be null
     * @param accepted The state of the notification, can be null
     * @return a managed {@link Notification} object
     * @throws IllegalArgumentException if any parameter is not correct
     */

    public Notification newNotification(String type, User user, Event event, Date nextSunnyDay, Boolean accepted) throws IllegalArgumentException{
        if (user == null || event == null) {
            throw new IllegalArgumentException();
        }
        if (!Arrays.asList(Notification.TYPE.CONST_ARRAY).contains(type)) {
            throw new IllegalArgumentException("type must be one from TYPE of Notification");
        }
        
        Notification notification = new Notification(type, false, DateTime.now().toDate());
        notification.setAccepted(accepted);
        notification.setEventId(event);
        notification.addUserToUserCollection(user);
        
        
        
        try {
            em.persist(notification);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Problem persisting notification {0} due to {1}", new Object[]{notification.getId(), e});
        }
        
        return notification;
    }
    
    /**
     * This method will create and return a new {@link Notification} object and persist 
     * it in the persistence context.
     * 
     * 
     * @param type The type of the new notification from {@link Notification.TYPE}
     * @param user A {@link User} object representig the user to which the notification refer
     * @param event A {@link Event} object representing the event to which the notification refer 
     * @return a managed {@link Notification} object
     * @throws IllegalArgumentException if any parameter is not correct
     */
    
    public Notification newNotification(String type, User user, Event event) throws IllegalArgumentException{
        return this.newNotification(type, user, event, null, null);
    }
  
    /**
     * This method will delete a {@link Notification}, passed as argument, from the persistence context,
     * if it is present in the persistence context. Otherwise it will throw an exception.
     * 
     * 
     * @param notification The {@link Notification} object representig the notification to remove. 
     * @throws IllegalArgumentException If the parameter is null or its primary key is null.
     * @throws NotificationNotFoundException If the notification is not found. 
     */
    public void deleteNotification(Notification notification) throws IllegalArgumentException, NotificationNotFoundException {
        if(notification == null)
            throw new IllegalArgumentException("Notification cannot be null");
        if(notification.getId() == null)
            throw new IllegalArgumentException("Notification id cannot be null");
        //Get the notification in order to remove it later from the persistence context
        Notification n = em.find(Notification.class, notification.getId());
        if(n == null)
            throw new NotificationNotFoundException("Notification not present in the presistence context");
        em.remove(n);
        em.flush();
    }
}
